/*
 * Copyright 2012 Zach Whaley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package me.zachwhaley.android;

import me.zachwhaley.android.provider.ListContract.Lists;
import me.zachwhaley.android.provider.ListContract.Things;
import me.zachwhaley.android.utils.AlertDialogs;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.CursorAdapter;
import android.widget.ListView;

public class ListsFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>
{
//	final static private String TAG = "ListsFragment";
	
	final static private int LOADER_ID = 0;
	
	final static private String[] PROJECTION = { Lists._ID, Lists.LIST_NAME };
	final static private String[] FROM = { Lists.LIST_NAME };
	final static private int[] TO = { android.R.id.text1 };

	private Activity mActivity;
	private SimpleCursorAdapter mAdapter;
	private Cursor mCursor;

	/**
	 * @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
	 */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		setHasOptionsMenu(true);
	}

	/**
	 * @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle)
	 */
	@Override
	public void onActivityCreated(Bundle savedInstanceState)
	{
		super.onActivityCreated(savedInstanceState);
		
		mActivity = getActivity();
		
		mAdapter = new SimpleCursorAdapter(mActivity, 
				android.R.layout.simple_list_item_1, null, FROM, TO, 
				CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

		// Set the list adapter
		setListAdapter(mAdapter);
		setEmptyText("No Lists...");

		getListView().setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
		registerForContextMenu(getListView());

		// Do not show the list until the data has loaded
		setListShown(false);
		getLoaderManager().initLoader(LOADER_ID, null, this);
	}

	/**
	 * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, android.os.Bundle)
	 */
	public Loader<Cursor> onCreateLoader(int id, Bundle bundle)
	{
		// Return a cursor loader with list IDs and names
		return new CursorLoader(mActivity, Lists.CONTENT_URI, PROJECTION, null, null, null);
	}

	/**
	 * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object)
	 */
	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
	{
		mAdapter.swapCursor(cursor);
		setListShownNoAnimation(true);	
	}

	/**
	 * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset(android.support.v4.content.Loader)
	 */
	public void onLoaderReset(Loader<Cursor> loader)
	{
		mAdapter.swapCursor(null);		
	}

	/**
	 * Restarts the cursor loader causing the view to refresh
	 */
	private void restartLoader()
	{
		getLoaderManager().restartLoader(LOADER_ID, null, this);
	}

	/**
	 * @see android.support.v4.app.ListFragment#onListItemClick(android.widget.ListView, android.view.View, int, long)
	 */
	@Override
	public void onListItemClick(ListView l, View v, int position, long id)
	{
		openItem(id);
	}

	/**
	 * Opens a new activity (or fragment) for the input List ID
	 * 
	 * @param id
	 *            list ID
	 */
	private void openItem(final long id)
	{
		final Intent intent = new Intent(mActivity, ThingsActivity.class);
		intent.putExtra(Things.LIST_ID, id);
		intent.putExtra(Lists.LIST_NAME, getList(id).getName());
		((BaseActivity) mActivity).openActivityOrFragment(intent);
	}

	private void renameList(final long id)
	{
		AlertDialogs.showInputDialog(mActivity, "Rename List", null, null, new AlertDialogs.InputCallBacks()
		{
			public void positiveButtonPressed(String text)
			{
				// Set the updated values
				ContentValues values = new ContentValues();
				values.put(Lists.LIST_NAME, text);
				updateList(id, values);

				// Restart the loader to reload the view.
				restartLoader();
			}
			public void negativeButtonPressed(String text)
			{
			}
		});
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean updateViewValue(View view, Cursor cursor, int columnIndex)
	{
		// Let the cursor adapter handle view binding
		return false;
	}



	/**
	 * {@inheritDoc}
	 */
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
	{
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.lists_menu, menu);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		// Find the given menu item
		switch (item.getItemId())
		{
		// Add a new list
		case R.id.new_list:
			addList();
			return true;
			// Sort the current lists
		case R.id.sort:
			// TODO: Sort the list by a given criteria
			return true;
			// Delete all lists
		case R.id.delete_lists:
			clearAll();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public void addList()
	{
		AlertDialogs.showInputDialog(mActivity, "New List", "Add", null, new AlertDialogs.InputCallBacks()
		{
			// If the add button was pressed
			public void positiveButtonPressed(String text)
			{
				// Insert the new list into the database
				ContentValues values = new ContentValues();
				values.put(Lists.LIST_NAME, text);
				mActivity.getContentResolver().insert(Lists.CONTENT_URI, values);
				
				restartLoader();
			}
			public void negativeButtonPressed(String text)
			{
			}
		});
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
	{
		super.onCreateContextMenu(menu, v, menuInfo);

		// Load the lists context menu items
		MenuInflater inflater = mActivity.getMenuInflater();
		inflater.inflate(R.menu.lists_context_menu, menu);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean onContextItemSelected(MenuItem item)
	{
		final long id = mAdapter.getItemId(mAdapter.getCursor().getPosition());
		// Find the given context menu item
		switch (item.getItemId())
		{
		// Rename the selected list
		case R.id.rename_list:
			renameList(id);
			return true;
			// Delete the selected list
		case R.id.delete:
			deleteList(id);
			return true;
		case R.id.open:
			// Open the selected list to shown it's items
			openItem(id);
			return true;
		default:
			return super.onContextItemSelected(item);
		}
	}

	public void clearAll()
	{
		AlertDialogs.showAlertDialog(mActivity, "Remove all lists?", "Yes", null, new AlertDialogs.AlertCallBacks()
		{
			public void positiveButtonPressed()
			{
				// Delete all lists from the database
				// this will subsequently delete all things in each list.
				mActivity.getContentResolver().delete(Lists.CONTENT_URI, null, null);

				// Restart the loader to reload the view.
				restartLoader();
			}
			public void negativeButtonPressed()
			{
			}
		});
	}

	public void deleteList(final long id)
	{
		AlertDialogs.showAlertDialog(mActivity, "Delete List?", "Yes", null, new AlertDialogs.AlertCallBacks()
		{
			public void positiveButtonPressed()
			{
				// Delete the selected list
				mActivity.getContentResolver().delete(ContentUris.withAppendedId(Lists.CONTENT_URI ,id), null, null);

				// Restart the loader to reload the view
				restartLoader();
			}
			public void negativeButtonPressed()
			{
			}
		});
	}
	
	public List getList(final long id)
	{
		mCursor = mActivity.getContentResolver().query(ContentUris.withAppendedId(Lists.CONTENT_URI ,id),
				PROJECTION, null, null, null);
		
		List list = new List(id);
		if (mCursor.moveToFirst())
		{
			list.setName(mCursor.getString(mCursor.getColumnIndex(Lists.LIST_NAME)));
		}
		mCursor.close();
		return list;
	}
	
	public int updateList(long id, ContentValues values)
	{
		values.put(Lists.LIST_EDITED, "NOW");
		return mActivity.getContentResolver().update(ContentUris.withAppendedId(Lists.CONTENT_URI ,id), values, null, null);
	}
}
